{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from concurrent.futures import ProcessPoolExecutor\n",
    "from pathlib import Path\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import torch\n",
    "\n",
    "from lhotse import CutSet, Fbank, LilcomFilesWriter, WavAugmenter\n",
    "from lhotse.dataset import SpeechRecognitionDataset\n",
    "from lhotse.recipes.librispeech import download_and_untar, prepare_librispeech, dataset_parts_full"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Settings for paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "root_dir = Path('data')\n",
    "corpus_dir = root_dir / 'LibriSpeech'\n",
    "output_dir = root_dir / 'librispeech_nb'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Select data parts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('dev-clean',\n",
       " 'dev-other',\n",
       " 'test-clean',\n",
       " 'test-other',\n",
       " 'train-clean-100',\n",
       " 'train-clean-360',\n",
       " 'train-other-500')"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset_parts_full"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_parts = ('dev-clean', 'test-clean', 'train-clean-100')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Download and untar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "download_and_untar(root_dir, dataset_parts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Prepare audio and supervision manifests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "librispeech_manifests = prepare_librispeech(corpus_dir, dataset_parts, output_dir)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [Optional] Data augmentation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "use_data_augmentation = False\n",
    "augmenter = WavAugmenter.create_predefined('pitch_reverb_tdrop', sampling_rate=16000) if use_data_augmentation else None\n",
    "# It seems when spawning multiple Python subprocesses with the same sox handle it raises \"std::runtime_error: Couldn't close file\"\n",
    "# The issue seems to happen only in a Jupyter notebook on Mac OS X, hence the work around below.\n",
    "if use_data_augmentation:\n",
    "    num_jobs = 1\n",
    "else:\n",
    "    num_jobs = os.cpu_count()\n",
    "    torch.set_num_threads(1)\n",
    "    torch.set_num_interop_threads(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extract features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "for partition, manifests in librispeech_manifests.items():\n",
    "    with LilcomFilesWriter(f'{output_dir}/feats_{partition}') as storage, ProcessPoolExecutor(num_jobs) as ex:\n",
    "        cut_set = CutSet.from_manifests(\n",
    "            recordings=manifests['recordings'],\n",
    "            supervisions=manifests['supervisions']\n",
    "        ).compute_and_store_features(\n",
    "            extractor=Fbank(),\n",
    "            storage=storage,\n",
    "            augmenter=augmenter if 'train' in partition else None,\n",
    "            executor=ex\n",
    "        ).pad()\n",
    "    librispeech_manifests[partition]['cuts'] = cut_set\n",
    "    cut_set.to_json(output_dir / f'cuts_{partition}.json.gz')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Make PyTorch Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "cuts_dev = SpeechRecognitionDataset(librispeech_manifests['dev-clean']['cuts'])\n",
    "cuts_train = SpeechRecognitionDataset(librispeech_manifests['train-clean-100']['cuts'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Illustration of an example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Transcript: HAD LAID BEFORE HER A PAIR OF ALTERNATIVES NOW OF COURSE YOU'RE COMPLETELY YOUR OWN MISTRESS AND ARE AS FREE AS THE BIRD ON THE BOUGH I DON'T MEAN YOU WERE NOT SO BEFORE BUT YOU'RE AT PRESENT ON A DIFFERENT FOOTING\n",
      "Supervisions mask: tensor([1., 1., 1.,  ..., 0., 0., 0.])\n",
      "Feature matrix:\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x144 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sample = cuts_train[0]\n",
    "print('Transcript:', sample['text'])\n",
    "print('Supervisions mask:', sample['supervisions_mask'])\n",
    "print('Feature matrix:')\n",
    "plt.matshow(sample['features'].transpose(0, 1).flip(0));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Make PyTorch Dataloader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_dl = torch.utils.data.DataLoader(cuts_train, batch_size=32, shuffle=True)\n",
    "dev_dl = torch.utils.data.DataLoader(cuts_dev, batch_size=32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "features - shape or length: torch.Size([32, 2452, 40])\n",
      "text - shape or length: 32\n",
      "supervisions_mask - shape or length: torch.Size([32, 2452])\n"
     ]
    }
   ],
   "source": [
    "for batch in train_dl:\n",
    "    for key, value in batch.items():\n",
    "        print(key, '- shape or length:', end=' ')\n",
    "        if isinstance(value, torch.Tensor):\n",
    "            print(value.shape)\n",
    "        else:\n",
    "            print(len(value))\n",
    "    break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
